package com.gscitysfy.cus.drain.modules.reserveplan.service.impl;

import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.alibaba.cloud.commons.lang.StringUtils;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gscitysfy.cus.drain.constants.DicConstant;
import com.gscitysfy.cus.drain.constants.RedisKeyConstant;
import com.gscitysfy.cus.drain.modules.inspection.entity.DrainInspectionMnProblem;
import com.gscitysfy.cus.drain.modules.reserveplan.dto.DrainReservePlanInfoDto;
import com.gscitysfy.cus.drain.modules.reserveplan.dto.DrainReservePlanMnCarDto;
import com.gscitysfy.cus.drain.modules.reserveplan.entity.DrainReservePlanInfo;
import com.gscitysfy.cus.drain.modules.reserveplan.mapper.DrainReservePlanControlInfoMapper;
import com.gscitysfy.cus.drain.modules.reserveplan.mapper.DrainReservePlanInfoMapper;
import com.gscitysfy.cus.drain.modules.reserveplan.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gscitysfy.cus.drain.modules.reserveplan.vo.DrainReservePlanInfoVo;
import com.gscitysfy.cus.drain.utils.HttpResponseUtil;
import com.gscitysfy.cus.drain.utils.RedisUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.util.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author shenglin
 * @since 2022-11-15 14:28:05
 */
@Service
public class DrainReservePlanInfoServiceImpl extends ServiceImpl<DrainReservePlanInfoMapper, DrainReservePlanInfo> implements IDrainReservePlanInfoService {

    @Resource
    private DrainReservePlanInfoMapper drainReservePlanInfoMapper;

    @Resource
    IDrainReservePlanControlInfoService drainReservePlanControlInfoService;

    @Resource
    IDrainReservePlanMnCarService drainReservePlanMnCarService;

    @Resource
    IDrainReservePlanMnMaterialService drainReservePlanMnMaterialService;

    @Resource
    IDrainReservePlanMnTeamService drainReservePlanMnTeamService;

    @Resource
    IDrainReservePlanLevelResponseService drainReservePlanLevelResponseService;

    @Resource
    private RedisUtil redisUtil;

    @Transactional(rollbackFor = Throwable.class)
    @Override
    public boolean deleteReservePlanInfoByIds(List<String> infoIds) {
        //删除基本信息
        List<DrainReservePlanInfo> old=new ArrayList<>();
        for (String infoId : infoIds) {
            DrainReservePlanInfo drainReservePlanInfo = drainReservePlanInfoMapper.selectById(infoId);
            drainReservePlanInfo.setCmUsable(true);
            old.add(drainReservePlanInfo);
        }
        boolean result = this.updateBatchById(old);
        //删除指挥体系的信息
        drainReservePlanControlInfoService.deletByInfoId(infoIds);
        //删除应急车辆信息
        drainReservePlanMnCarService.deletByInfoId(infoIds);
        //删除应急物资信息
        drainReservePlanMnMaterialService.deletByInfoId(infoIds);
        //删除应急队伍信息
        drainReservePlanMnTeamService.deletByInfoId(infoIds);
        //删除预案预警等级和响应机制
        drainReservePlanLevelResponseService.deletByInfoId(infoIds);
        return result;
    }

    @Override
    public IPage<DrainReservePlanInfo> getReservePlanInfoList(DrainReservePlanInfoVo drainReservePlanInfoVo) {
        LambdaQueryWrapper<DrainReservePlanInfo> queryWrapper = new LambdaQueryWrapper<>();
        // 查询条件判断预案类别
        if (StringUtils.isNotEmpty(drainReservePlanInfoVo.getTypeCode())) {
            queryWrapper.eq(DrainReservePlanInfo::getTypeCode, drainReservePlanInfoVo.getTypeCode());
        }
        //预案名称模糊查询
        if (StringUtils.isNotEmpty(drainReservePlanInfoVo.getName())) {
            queryWrapper.like(DrainReservePlanInfo::getName, drainReservePlanInfoVo.getName());
        }
        //预案状态1.启用,0禁用
        if (StringUtils.isNotEmpty(drainReservePlanInfoVo.getStatus())) {
            queryWrapper.eq(DrainReservePlanInfo::getStatus, drainReservePlanInfoVo.getStatus());
        }
        // 判断发布时间
        if (Objects.nonNull(drainReservePlanInfoVo.getCmStartPublishTime())) {
            queryWrapper.ge(DrainReservePlanInfo::getPublishTime, drainReservePlanInfoVo.getCmStartPublishTime());
        }
        if (Objects.nonNull(drainReservePlanInfoVo.getCmEndPublishTime())) {
            queryWrapper.le(DrainReservePlanInfo::getPublishTime, drainReservePlanInfoVo.getCmEndPublishTime());
        }
        queryWrapper.eq(DrainReservePlanInfo::getCmUsable,false);
        //根据预案的添加时间倒序
        queryWrapper.orderByDesc(DrainReservePlanInfo::getCmAddtime);
        return this.page(new Page<>(drainReservePlanInfoVo.getCurrent(), drainReservePlanInfoVo.getSize()), queryWrapper);
    }

    public List<DrainReservePlanInfo> getDrainReservePlanInfoList(DrainReservePlanInfoVo drainReservePlanInfoVo) {
        LambdaQueryWrapper<DrainReservePlanInfo> queryWrapper = new LambdaQueryWrapper<>();
        //预案ids不为空时
        if(drainReservePlanInfoVo.getIds()!=null&&!drainReservePlanInfoVo.getIds().isEmpty()){
            queryWrapper.in(DrainReservePlanInfo::getCmKid,drainReservePlanInfoVo.getIds());
        }else {
        // 查询条件判断预案类别
        if (StringUtils.isNotEmpty(drainReservePlanInfoVo.getTypeCode())) {
            queryWrapper.eq(DrainReservePlanInfo::getTypeCode, drainReservePlanInfoVo.getTypeCode());
        }
        //预案名称模糊查询
        if (StringUtils.isNotEmpty(drainReservePlanInfoVo.getName())) {
            queryWrapper.like(DrainReservePlanInfo::getName, drainReservePlanInfoVo.getName());
        }
        // 判断发布时间
        if (Objects.nonNull(drainReservePlanInfoVo.getCmStartPublishTime())) {
            queryWrapper.ge(DrainReservePlanInfo::getPublishTime, drainReservePlanInfoVo.getCmStartPublishTime());
        }
        if (Objects.nonNull(drainReservePlanInfoVo.getCmEndPublishTime())) {
            queryWrapper.le(DrainReservePlanInfo::getPublishTime, drainReservePlanInfoVo.getCmStartPublishTime());
        }
        }
        //根据预案的添加时间倒序
        queryWrapper.orderByDesc(DrainReservePlanInfo::getCmAddtime);
        queryWrapper.eq(DrainReservePlanInfo::getCmUsable,false);
        return this.list(queryWrapper);
    }

    @Override
    public void exportReservePlanInfoFile(HttpServletResponse response, DrainReservePlanInfoVo drainReservePlanInfoVo) {
        try (ExcelWriter writer = ExcelUtil.getWriter(true); OutputStream out = response.getOutputStream()) {

            String filename = "预案信息表.xlsx";
            HttpResponseUtil.setResponseHeaders(response, filename);
            writer.setOnlyAlias(true);
            //设置默认宽度
            writer.setColumnWidth(-1,20);
            //设置表头
            writer.addHeaderAlias("name", "预案名称");
            writer.addHeaderAlias("typeCode", "预案类别");
            writer.addHeaderAlias("publishTime", "发布时间");
            writer.addHeaderAlias("status", "预案状态");
            writer.addHeaderAlias("manageUnit", "管理单位");

            List<DrainReservePlanInfo> drainReservePlanInfos = getDrainReservePlanInfoList(drainReservePlanInfoVo);

            //判空，单独写入头数据
            if (drainReservePlanInfos.isEmpty()) {
                writer.writeHeadRow(new ArrayList<String>() {{
                    add("预案名称");
                    add("预案类别");
                    add("发布时间");
                    add("预案状态");
                    add("管理单位");
                }});
            } else {
                Map<Object, Object> problemBasis = redisUtil.hmget(RedisKeyConstant.DATA_DICT_KEY + DicConstant.RESERVE_PLAN_TYPE);
                drainReservePlanInfos.forEach(item -> {
                    if(problemBasis.get(item.getTypeCode())!=null){
                        item.setTypeCode(problemBasis.get(item.getTypeCode()).toString());
                    }
                    item.setStatus(item.getStatus().equals("1")?"启用":"禁用");
                });
                writer.write(drainReservePlanInfos, true);
                writer.flush(out);
            }

        } catch (IOException e) {
            log.error("export Problem list error!");
        }
    }

    @Override
    public DrainReservePlanInfoDto getReservePlanInfoById(String id) {
        DrainReservePlanInfoDto result =new DrainReservePlanInfoDto();
        DrainReservePlanInfo drainReservePlanInfo = drainReservePlanInfoMapper.selectById(id);
        if(drainReservePlanInfo!=null&&StringUtils.isNotBlank(drainReservePlanInfo.getTypeCode())){
            //获取预案基础信息
            BeanUtils.copyProperties(drainReservePlanInfo,result);
            Map<Object, Object> problemBasis = redisUtil.hmget(RedisKeyConstant.DATA_DICT_KEY + DicConstant.RESERVE_PLAN_TYPE);
            if(problemBasis.get(drainReservePlanInfo.getTypeCode())!=null){
                result.setTypeCodeDesc(problemBasis.get(drainReservePlanInfo.getTypeCode()).toString());
            }
        }
        //获取当前预案的指挥体系信息
        result.setControlInfoList(drainReservePlanControlInfoService.getReservePlanControlInfoList(id));
        //获取当前预案的应急车辆信息
        result.setMnCarList(drainReservePlanMnCarService.getReservePlanMnCarInfoList(id, null));
        //获取当前预案的应急队伍信息
        result.setMnTeamDtoList(drainReservePlanMnTeamService.getReservePlanMnTeamInfoList(id, null));
        //获取当前预案的划分标准和响应机制信息
        result.setLevelResponse(drainReservePlanLevelResponseService.getById(id));
        //获取当前预案的应急物资信息
        result.setMnMaterialList(drainReservePlanMnMaterialService.getReservePlanMnMaterialInfoList(id,null));
        return result;
    }
}
